package it.polito.let.jhp.types;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class TypeList implements Serializable {

	private static final long serialVersionUID = -8963581443491194774L;

	private List<JHPType> list = new LinkedList<JHPType>();

	private List<TypeCode> leafTypes = new ArrayList<TypeCode>(){
		private static final long serialVersionUID = -7595367281203334902L;
		{ add(TypeCode.ENUM); }
	};

	private boolean restrictable=true; 
	private boolean multiType=false;

	public TypeList (TypeList l) {
		addType(l);
	}

	public TypeList (JHPType t) {
		this(t,true);
	}

	public TypeList (JHPType t, boolean restrictable) {
		list.add(t);
		this.restrictable = restrictable;
	}

	public void addType(JHPType t)
	{
		list.add(t);
		if (list.size() > 1 )
		{
			restrictable = false;
			multiType = true;
		}
		if (leafTypes.contains(t.getOriginalType()))
			restrictable = false;	

	}

	public void addType(TypeList t)
	{
		list.addAll(t.getList());
		if (list.size() > 1 )
		{
			restrictable = false;
			multiType = true;
		}
		if (leafTypes.contains(t.getType().getOriginalType()))
			restrictable = false;	
	}

	public boolean isRestrictable() {
		return restrictable;
	}

	public JHPType getType() {
		return list.get(0);
	}

	List<JHPType> getList() {
		return list;
	}

	public void addType(List<JHPType> list2) {
		list.addAll(list2);

	}

	public boolean typeCheck(Object o, TypeCode t) {
		for (JHPType jhpt:list) {
			if (jhpt.typeCheck(o, t) == true)
				return true;
		}
		return false;
	}

	public boolean typeCheck(Value v) {
		return typeCheck(v.getVal(), v.getType());
	}

	public String clientSideCheck(String value) {
		StringBuffer result = new StringBuffer("( ");
		for (int i=0; i<list.size(); i++) {
			if (i>0)
				result.append(" || ");
			result.append(list.get(i).clientSideCheck(value));
		}
		result.append(")");
		return result.toString();
	}


	@Override
	public String toString()
	{
		StringBuffer res = new StringBuffer();

		res.append(list.get(0).toString());

		for (int i=1; i<list.size(); i++)
		{
			res.append(" OR ");
			res.append(list.get(i).toString());		
		}
		return res.toString();	
	}
	
	public boolean isList()
	{
	 return multiType;	
	}
}

